#include "ReceptionInfosProxy.h"
#include "socket_utils.h"

/*************************************************************************
                        ReceptionInfosProxy  -  description
                             -------------------

*************************************************************************/

//---------- Réalisation de la tâche <ReceptionInfosProxy> (fichier ReceptionInfosProxy.cpp) ---



//------------------------------------------------------ Fonctions privées

char * recupererTrameRefCapt()
{
	MYSQL mysql;
	MYSQL_RES *result = NULL;
	MYSQL_ROW *row = NULL;

	char req[1024] = ADRESSE_BOITIER;

	//buffer qui contiendra les id et type de capteurs extraits de la BDD
	char buff[1024] = "";
	//Requête qui sélectionne touts les capteurs référencés en BDD
	char requeteBDD[] = "SELECT identifiantCapteur, codeTypeSource FROM source, typesource where source.idTypeSource = typesource.idTypeSource";
	mysql_init(&mysql);
	//Connexion à la BDD
	if (mysql_real_connect(&mysql, MYSQL_HOST, MYSQL_LOGIN, MYSQL_PASSWD, MYSQL_DB, 0, NULL, 0) == NULL) {
		printf("[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur de connexion à la BDD : %s\n", mysql_error(&mysql));
		mysql_close(&mysql);
	}
	else if (mysql_select_db(&mysql,MYSQL_DB) == 0) {
		printf("[ReceptionInfosProxy/recupererTrameRefCapt()] Connecté à la BDD!\n");

		if(mysql_query(&mysql, requeteBDD))
		{
			perror("[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur requête capteurs\n");
			return req;
		}
		else
		{
			//Déclaration des pointeurs de structure
			unsigned int i = 0;
			unsigned int num_champs = 0;

			//On met le jeu de résultat dans le pointeur result
			result = mysql_store_result(&mysql);
			if(result)
			{
				//On récupère le nombre de champs
				num_champs = mysql_num_fields(result);
				int nbCapt = 0;
				//Tant qu'il y a encore un résultat ...
				while ((row = mysql_fetch_row(result)))
				{
					//On déclare un pointeur long non signé pour y stocker la taille des valeurs
					unsigned long *lengths;

					//On stocke cette taille dans le pointeur
					lengths = mysql_fetch_lengths(result);

					//On fait une boucle pour avoir la valeur de chaque champs
					for(i = 0; i < num_champs; i++)
					{
						strcat(buff,"$");
						strcat(buff,row[i]);
					}
					nbCapt++;
				}
				//Libération du jeu de résultat
				mysql_free_result(result);

				//copie du nombre de capteurs dans la trame
				sprintf(req,"%s%s%i",req,"$",nbCapt);
				//copie des id et types de capteurs dans la trame
				strcat(req,buff);

			}
			else
			{
				if (mysql_errno(&mysql))
				{
					fprintf(stderr, "[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur: %s\n", mysql_error(&mysql));
				}
				else if (mysql_field_count(&mysql) == 0)
				{
					printf("[ReceptionInfosProxy/recupererTrameRefCapt()] aucun capteur trouvé\n");
					//return req;
				}
			}
		}


		//actionneurs
		MYSQL_RES *result2 = NULL;
		MYSQL_ROW *row2 = NULL;
		//Récupération de la liste des actionneurs
		char requeteBDD2[] = "SELECT identifiantActionneur, codeTypeActionneur FROM actionneur, typeactionneur where actionneur.idTypeActionneur = typeactionneur.idTypeActionneur";
		char buff2[1024] = "";
		if(mysql_query(&mysql, requeteBDD2))
		{
			printf("[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur requête actionneurs\n");
			return req;
		}
		else
		{
			//Déclaration des pointeurs de structure
			unsigned int i = 0;
			unsigned int num_champs = 0;

			//On met le jeu de résultat dans le pointeur result
			result2 = mysql_store_result(&mysql);
			if(result2)
			{
				//On récupère le nombre de champs
				num_champs = mysql_num_fields(result2);
				int nbAct = 0;
				//Tant qu'il y a encore un résultat ...
				while ((row2 = mysql_fetch_row(result2)))
				{
					//On déclare un pointeur long non signé pour y stocker la taille des valeurs
					unsigned long *lengths;

					//On stocke cette taille dans le pointeur
					lengths = mysql_fetch_lengths(result2);

					//On fait une boucle pour avoir la valeur de chaque champs
					for(i = 0; i < num_champs; i++)
					{
						strcat(buff2,"$");
						strcat(buff2,row2[i]);
					}
					nbAct++;
				}
				//Libération du jeu de résultat
				mysql_free_result(result2);

				//copie du nombre de capteurs dans la trame
				sprintf(req,"%s%s%i%s",req,"$",nbAct,buff2);
			}
			else
			{
				if (mysql_errno(&mysql))
				{
					fprintf(stderr, "[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur: %s\n", mysql_error(&mysql));
				}
				else if (mysql_field_count(&mysql) == 0)
				{
					printf("[ReceptionInfosProxy/recupererTrameRefCapt()] aucun actionneur trouvé\n");
					return req;
				}
			}
		}
		return req;

	}
	else {
		perror("[ReceptionInfosProxy/recupererTrameRefCapt()] Erreur de connexion à la BDD!\n");
	}
	printf("[ReceptionInfosProxy/recupererTrameRefCapt()] Fermeture de la connexion\n");
	mysql_close(&mysql);

}

void ReceptionInfosProxyInit(int balInfo)
{
	idBalInfos = balInfo;
}

void ReceptionInfosProxyMoteur()
{
	SOCKET sock = init_connection(PORT_ECOUTE, MAX_CLIENTS);
   char buffer[BUF_SIZE];
   /* the index for the array */
   int actual = 0;
   int max = sock;
   /* an array for all clients sockets */
   //SOCKET clients[MAX_CLIENTS];

   fd_set rdfs;

   while(1)
   {
	  int i = 0;
	  FD_ZERO(&rdfs);

	  /* add STDIN_FILENO */
	  FD_SET(STDIN_FILENO, &rdfs);

	  /* add the connection socket */
	  FD_SET(sock, &rdfs);

	  /* add socket of each client */
	  for(i = 0; i < actual; i++)
	  {
		 FD_SET(clients[i], &rdfs);
	  }

	  if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
	  {
		 perror("[ReceptionInfosProxyMoteur] select()");
		 exit(errno);
	  }

	  /* something from standard input : i.e keyboard */
	  if(FD_ISSET(STDIN_FILENO, &rdfs))
	  {
		 /* stop process when type on keyboard */
		 break;
	  }
	  else if(FD_ISSET(sock, &rdfs))
	  {
		 /* new client */
		 SOCKADDR_IN csin = { 0 };
		 size_t sinsize = sizeof csin;
		 int csock = accept(sock, (SOCKADDR *)&csin, &sinsize);
		 if(csock == SOCKET_ERROR)
		 {
			perror("[ReceptionInfosProxyMoteur] accept()");
			char descrp[] = "problème au niveau de l'accept() du serveur";
			logEvent(2,descrp);
			continue;
		 }
		 printf("[ReceptionInfosProxyMoteur] Nouveau client sur le socket %i\n", csock);
		 char descrp2[] = "nouvelle connexion du proxy au serveur";
		 logEvent(1 ,descrp2);

		 /* after connecting the client sends its name */
		 /*if(read_client(csock, buffer, BUF_SIZE) == -1)
		 {
			//disconnected
			continue;
		 }*/

		 char buff[BUF_SIZE]; //TODO : avant y avait MAX_LINE
		 strcpy(buff,recupererTrameRefCapt());
		 sprintf(buff,"%s%s", buff, "$");
		 printf("[ReceptionInfosProxyMoteur] Commande d'initialisation du proxy : %s\n", buff);
		 write_client(csock, buff);
		 char descrp3[] = "envoi des données d'initialisation par le serveur au proxy";
		 logEvent(1 ,descrp3);
		 /* what is the new maximum fd ? */
		 max = csock > max ? csock : max;

		 FD_SET(csock, &rdfs);

		 //strncpy(c.name, buffer, BUF_SIZE - 1);
		 clients[actual] = csock;
		 actual++;
	  }
	  else
	  {
		 int i = 0;
		 for(i = 0; i < actual; i++)
		 {
			/* a client is talking */
			if(FD_ISSET(clients[i], &rdfs))
			{
			   SOCKET client = clients[i];

			   printf("[ReceptionInfosProxyMoteur] Attente que le client parle\n");
			   int c = read_client(clients[i], buffer, BUF_SIZE);
			   /* client disconnected */
			   if(c == 0)
			   {
				  close(clients[i]);
				  remove_client(clients, i, &actual);
				  //strncpy(buffer, client, BUF_SIZE - 1);
				  //strncat(buffer, " disconnected !", BUF_SIZE - strlen(buffer) - 1);
				  //send_message_to_all_clients(clients, client, actual, buffer, 1);
				  printf("[ReceptionInfosProxyMoteur] Client %i a été déconnecté\n", client);
				  char descrp4[] = "deconnexion proxy du serveur";
				  logEvent(1 ,descrp4);
			   }
			   else
			   {
				   printf("[ReceptionInfosProxyMoteur] Message recu : %s\n", buffer + 2 * sizeof(char)); //TODO : trouver pk les 2 premieres cases de buffer avec le message de Hoang empechent de l'afficher
				   char descrp5[] = "reception d'un message du proxy sur le serveur";
				   logEvent(1 ,descrp5);
				   /*int i = 0;
				   for (i=0; i<15 ; i++) printf("buffer[%i] : %c\n", i, buffer[i]);*/
				   ParserTrame(buffer + 2 * sizeof(char), idBalInfos);
				   //ParserTrame(buffer, idBalInfos);
				   
				  //send_message_to_all_clients(clients, client, actual, buffer, 0);
			   }
			   break;
			}
		 }
	  }
   }
   end_connection(sock);
}

//////////////////////////////////////////////////////////////////  PUBLIC
//---------------------------------------------------- Fonctions publiques
void ReceptionInfosProxy(void* bal)
{
	//char message[]="01$12.4%02$13.5";

	printf("[ReceptionInfosProxy] Thread ReceptionInfosProxy démarré\n");
	int balInfo = (int)bal;
	ReceptionInfosProxyInit(balInfo);
	ReceptionInfosProxyMoteur();
	//ParserTrame(message);
}


